package bean;

import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;

import bean.Cliente;
import bean.vo.ClienteVO;
import bean.vo.CondicionPagoVO;
import bean.vo.DescuentoPorCantidadVO;


@Entity 
@Table( name = "clientes" )
@SuppressWarnings({"unchecked"})
public class Cliente extends EntidadPersistente {
	private String cuit;
	private String razonSocial;
	private String telefono;
	@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH} )
	@Cascade( org.hibernate.annotations.CascadeType.SAVE_UPDATE)
	private Direccion direccion;
	private Float descuentoPagoContado;
	@ManyToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH} )
	@Cascade( org.hibernate.annotations.CascadeType.SAVE_UPDATE)
	private List<CondicionPago> condicionesPago;
	@ManyToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH} )
	@Cascade( org.hibernate.annotations.CascadeType.SAVE_UPDATE)
	private List<DescuentoPorCantidad> descuentos;
	
	public Cliente () {
		this.condicionesPago = new ArrayList<CondicionPago>();
		this.descuentos = new ArrayList<DescuentoPorCantidad>();
	}
	
	public Cliente (String cuit) throws Exception{
		this();
		
		if (cuit == null || cuit.equalsIgnoreCase("")) {
			throw new Exception("ERROR - Cuit es requerido.");
		}
		this.cuit = cuit;
	}
	
	public Cliente (String cuit, String razonSocial, String telefono, Direccion direccion) throws Exception{
		this(cuit);
		
		if (razonSocial == null || razonSocial.equalsIgnoreCase("")) {
			throw new Exception("ERROR - Razon Social es requerido.");
		}
		
		this.razonSocial = razonSocial;
		this.telefono = telefono;
		this.direccion = direccion;
	}
	
	public ClienteVO getVO() {
		ClienteVO vo = new ClienteVO();
		vo.setCuit(cuit);
		vo.setRazonSocial(razonSocial);
		vo.setTelefono(telefono);
		vo.setDireccion(direccion != null ? direccion.getVO() : null);
		vo.setDescuentoPagoContado(descuentoPagoContado);
		vo.setCondicionesPago(new VOList<CondicionPagoVO>().getVoList(condicionesPago));
		vo.setDescuentos(new VOList<DescuentoPorCantidadVO>().getVoList(descuentos));
		
		return vo;
	}
	
	public String getCuit() {
		return cuit;
	}
	
	public void setCuit(String cuit) {
		this.cuit = cuit;
	}
	
	public String getRazonSocial() {
		return razonSocial;
	}
	
	public void setRazonSocial(String razonSocial) {
		this.razonSocial = razonSocial;
	}
	
	public Direccion getDireccion() {
		return direccion;
	}
	
	public void setDireccion(Direccion direccion) {
		this.direccion = direccion;
	}
	
	public Float getDescuentoPagoContado() {
		return descuentoPagoContado;
	}
	
	public void setDescuentoPagoContado(Float descuentoPagoContado) {
		this.descuentoPagoContado = descuentoPagoContado;
	}
	
	public List<CondicionPago> getCondicionesPago() {
		return condicionesPago;
	}
	
	public void setCondicionesPago(List<CondicionPago> condicionesPago) {
		this.condicionesPago = condicionesPago;
	}
	
	public List<DescuentoPorCantidad> getDescuentos() {
		return descuentos;
	}
	
	public void setDescuentos(List<DescuentoPorCantidad> descuentos) {
		this.descuentos = descuentos;
	}

	public String getTelefono() {
		return telefono;
	}

	public void setTelefono(String telefono) {
		this.telefono = telefono;
	}
	
	public boolean agregarCondicionPago(CondicionPago cp){
		boolean tieneCondicionPago = condicionesPago.contains(cp);
		if (!tieneCondicionPago){
			condicionesPago.add(cp);
		}
		
		return !tieneCondicionPago;
	}
	
	public boolean eliminarCondicionPago(CondicionPago cp)
	{
		boolean tieneCondicionPago = condicionesPago.contains(cp);
		if (tieneCondicionPago){
			condicionesPago.remove(cp);
		}
		
		return tieneCondicionPago;
	}
	
	public boolean agregarDescuentoPorCantidad (DescuentoPorCantidad dpc){
		boolean tieneDescuento = descuentos.contains(dpc);
		if (!tieneDescuento){
			descuentos.add(dpc);
		}
		
		return !tieneDescuento;
	}
	
	public boolean eliminarDescuentoPorCantidad (DescuentoPorCantidad dpc){
		boolean tieneDescuento = descuentos.contains(dpc);
		if (tieneDescuento){
			descuentos.remove(dpc);
		}
		
		return tieneDescuento;
	}
	
	@Override
	public int hashCode() {
		final int primo = 31;
		int result = 1;
		result = primo * (result + (cuit == null ? 0 : cuit.hashCode()));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) return true;	
		if ((obj == null) || (!(obj instanceof Cliente))) {
			return false;
		}
		Cliente otro = (Cliente) obj;
		return cuit!=null && otro.getCuit() != null ? (otro.getCuit().equals(cuit)) : false;
	}
}
